#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include "game.h"
#include "player.h"





void init_player(PLAYER* player, int x, int y) {
	player -> head_dir_x = 1;
	player -> head_dir_y = 0;
	
	player -> next_head_dir_x = 1;
	player -> next_head_dir_y = 0;
	
	player -> length = 6;
	player -> head_ptr = player -> length - 1;
	player -> body = malloc(sizeof(POINT*) * player -> length);

	player -> old_tail = NULL;
	
	for (int i = 0; i < player -> length; i++) {
		POINT* pt = malloc(sizeof(POINT));
		pt -> x = x + i;
		pt -> y = y;
		player -> body[i] = pt;
	}
}

void destroy_player(PLAYER* player) {
	for (int i = 0; i < player -> length; i++) {
		free(player -> body[i]);
	}
	if (player -> old_tail)
		free(player -> old_tail);
	free(player -> body);
	free(player);
}


int bit_self(PLAYER* player, POINT* head_pos) {
	for (int i = 0; i < player -> length; i++) {
		if (player -> body[i] != head_pos &&
			player -> body[i] -> x == head_pos -> x &&
			player -> body[i] -> y == head_pos -> y) {
			
			return 1;
		}
	}
	return 0;
}

int hit_head(FIELD* field, POINT* head) {
	return head -> x == 0 ||
		head -> y == 0 ||
		head -> x == field -> width - 1 ||
		head -> y == field -> height - 1;
}


void move_player(FIELD* field) {
	PLAYER* player = field -> player;
	
	player -> head_dir_x = player -> next_head_dir_x;
	player -> head_dir_y = player -> next_head_dir_y;
	
	POINT* oldhead = player -> body[player -> head_ptr];
	player -> head_ptr = (player -> head_ptr + 1) % player -> length;
	free(player -> old_tail);
	player -> old_tail = player -> body[player -> head_ptr];
	POINT* newhead = malloc(sizeof(POINT));
	newhead -> x = oldhead -> x + player -> head_dir_x;
	newhead -> y = oldhead -> y + player -> head_dir_y;
	
	for (int i = 0; i < field -> ball_count; i++) {
		if (field -> balls[i] -> position.x == newhead -> x &&
			field -> balls[i] -> position.y == newhead -> y) {
				eat_ball(field, i);
			}
	}
	
	player -> body[player -> head_ptr] = newhead;
	if (bit_self(player, newhead) ||
		hit_head(field, newhead)) {
			
		set_lost(field -> state);
	}
	
}

void handle_control(PLAYER* player) {
	int ch = getch();
	switch(ch) {
		case CTRL_LEFT:
		case 'h':
		case 'a':
			if (player -> head_dir_x != 1) {
				player -> next_head_dir_x = -1;
				player -> next_head_dir_y = 0;
			}
			break;
		case CTRL_RIGHT:
		case 'l':
		case 'd':
			if (player -> head_dir_x != -1) {
				player -> next_head_dir_x = 1;
				player -> next_head_dir_y = 0;
			}
			break;
		case CTRL_UP:
		case 'k':
		case 'w':
			if (player -> head_dir_y != 1) {
				player -> next_head_dir_x = 0;
				player -> next_head_dir_y = -1;
			}
			break;
		case CTRL_DOWN:
		case 'j':
		case 's':
			if (player -> head_dir_y != -1) {
				player -> next_head_dir_x = 0;
				player -> next_head_dir_y = 1;
			}
			break;
		default:
			break;
	}
}

int is_on_player(PLAYER* player, POINT* point) {
	for (int i = 0; i < player -> length; i++) {
		if (player -> body[i] -> x == point -> x &&
			player -> body[i] -> y == point -> y) {
			
			return 1;
		}
	}
	return 0;
}
